﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using PGMHelper;
using System.Windows.Forms.DataVisualization.Charting;

namespace Spectrum
{
    [JsonObject(MemberSerialization.OptIn)]
    /// <summary>
    /// 反应谱参数
    /// </summary>
    public class SpectParam
    {
        [JsonProperty]
        /// <summary>
        /// 影响系数
        /// </summary>
        public float Afa { set; get; }

        [JsonProperty]
        /// <summary>
        /// 速度
        /// </summary>
        public float Velocity { set; get; }

        [JsonProperty]
        /// <summary>
        /// 位移
        /// </summary>
        public float Disp { set; get; }

        [JsonProperty]
        /// <summary>
        /// 周期值
        /// </summary>
        public float Period { set; get; }

        /// <summary>
        /// 获得值
        /// </summary>
        /// <param name="SpectEnum"></param>
        /// <returns></returns>
        public float GetValue(SpectrumType SpectEnum)
        {
            switch(SpectEnum)
            {
                case SpectrumType.Afa: return this.Afa;
                case SpectrumType.Disp: return this.Disp;
                case SpectrumType.Velocity: return this.Velocity;
                case SpectrumType.Period: return this.Period;
                default: return this.Afa;
            }
        }

        /// <summary>
        /// 反应谱调幅度
        /// </summary>
        /// <param name="factor"></param>
        public void SpectrumAmplitude(float factor)
        {
            this.Afa *= factor;
            this.Velocity *= factor;
            this.Disp *= factor;
        }

        /// <summary>
        /// 获得相应最大值
        /// </summary>
        /// <param name="response"></param>
        public void SetSpectrum(ResponseSet response, bool isPeseudo)
        {
            this.Afa = Math.Max(this.Afa, response.GetAfaMax(isPeseudo));
            this.Velocity = Math.Max(this.Velocity, response.GetVelocityMax(isPeseudo));
            this.Disp = Math.Max(this.Disp, response.Umax);
        }

        /// <summary>
        /// 线性插值
        /// </summary>
        /// <param name="paramJ"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        public SpectParam Interpolation(SpectParam paramJ, float period)
        {
            //求得斜率
            float Afaslope = (paramJ.Afa - this.Afa) / (paramJ.Period - this.Period);
            float Velocityslope = (paramJ.Velocity - this.Velocity) / (paramJ.Period - this.Period);
            float Dispslope = (paramJ.Disp - this.Disp) / (paramJ.Period - this.Period);
            //线性插值求得加速度
            float afa = Afaslope * (period - this.Period) + this.Afa;
            float v = Velocityslope * (period - this.Period) + this.Velocity;
            float d = Dispslope * (period - this.Period) + this.Disp;
            //返回参数
            return new SpectParam(period, afa, v, d);
        }

        /// <summary>
        /// 空的构造函数
        /// </summary>
        public SpectParam()
        {

        }

        /// <summary>
        /// 构造反应谱值
        /// </summary>
        /// <param name="period"></param>
        /// <param name="isPeseudo"></param>
        /// <param name="response"></param>
        public SpectParam(float period, bool isPeseudo, ResponseSet response)
        {
            //获得响应最大值
            this.SetSpectrum(response, isPeseudo);
            //获得周期
            this.Period = period;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="period"></param>
        /// <param name="afa"></param>
        public SpectParam(float period, float afa, float velocity, float disp)
        {
            this.Period = period;
            this.Afa = afa;
            this.Velocity = velocity;
            this.Disp = disp;
        }

        /// <summary>
        /// 反应谱计算相对误差
        /// </summary>
        /// <param name="param"></param>
        public SpectParam(SpectParam originParam, SpectParam newParam)
        {
            this.Afa = (newParam.Afa - originParam.Afa) / originParam.Afa;
            this.Velocity = (newParam.Velocity - originParam.Velocity) / originParam.Velocity;
            this.Disp = (newParam.Disp - originParam.Disp) / originParam.Disp;
            //判断周期值是否相等
            if (Math.Abs(originParam.Period - newParam.Period) > 0.1)
                MessageBoxExtern.Error("周期错误");
            this.Period = originParam.Period;
        }
    }
}
